package com.tool.cn.util;

import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Logger;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

import org.apache.commons.codec.binary.Base64;

import com.sun.media.jai.codec.BMPEncodeParam;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.JPEGEncodeParam;
import com.sun.media.jai.codec.TIFFEncodeParam;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;



/**
 * 图片工具类
 * @author wangzh
 * 2018年6月26日 下午5:24:02
 */
@SuppressWarnings("all")
public class ImageUtil {
	
	private static Logger log = Logger.getLogger(ImageUtil.class.getName());
	
    /**
     * 将图片转换成Base64编码
     * @param imgFile 待处理图片
     */
    public static String imageToStr(String imgFile){
        //将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try {
            in = new FileInputStream(imgFile);        
            data = new byte[in.available()];
            in.read(data);
            in.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        return new String(Base64.encodeBase64(data));
    }
    
    /**
     * 对字节数组字符串进行Base64解码并生成图片
     * @param imgStr 图片数据
     * @param imgFilePath 保存图片全路径地址
     * @return
     */
    public static boolean strToImage(String imgStr,String imgFilePath){
        if (imgStr == null) //图像数据为空
            return false;
     
        try{
            //Base64解码
            byte[] b = Base64.decodeBase64(imgStr);
            for(int i=0;i<b.length;++i)
            {
                if(b[i]<0)
                {//调整异常数据
                    b[i]+=256;
                }
            }
            
            //存储目录判断生成
            File file=new File(imgFilePath);
            if(!file.getParentFile().exists()) {
            	file.getParentFile().mkdirs();
            }
            
            //生成jpeg图片
            OutputStream out = new FileOutputStream(imgFilePath);    
            out.write(b);
            out.flush();
            out.close();
            return true;
        }catch (Exception e){
            return false;
        }
    }
    
	/**
	 * tif转jpg 
	 * @param tifImage
	 */
    public static void tifToJpg(String tifImage) {
        if (tifImage == null || "".equals(tifImage.trim())){
            return ;    
        }
        if (!new File(tifImage).exists()){
        	log.info("系统找不到指定文件："+tifImage);
            return ;
        }
        FileSeekableStream fileSeekStream = null;
        try {
            fileSeekStream = new FileSeekableStream(tifImage);
            JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
            ImageDecoder dec = ImageCodec.createImageDecoder("tiff", fileSeekStream, null);
            int count = dec.getNumPages();
            log.info("tif文件共有[" + count + "]页");
            String filePathPrefix = tifImage.substring(0, tifImage.lastIndexOf("."));
            for (int i = 0; i < count; i++) {
                RenderedImage renderedImage = dec.decodeAsRenderedImage(i);
                File imgFile = new File(filePathPrefix + "_" + i + ".jpg");
                log.info("第"+i+"分别保存至： " + imgFile.getCanonicalPath());
                ParameterBlock pb = new ParameterBlock();
                pb.addSource(renderedImage);
                pb.add(imgFile.toString());
                pb.add("JPEG");
                pb.add(jpegEncodeParam);
                RenderedOp renderedOp = JAI.create("filestore",pb);
                renderedOp.dispose();
            }
        } catch (IOException e) {
            log.info(e.toString());
        } finally {
            if (fileSeekStream != null){
                try {
                    fileSeekStream.close();
                } catch (IOException e) {
                }
                fileSeekStream = null;
            }
        }
    }
    
    /**
     * jpg转tif
     */
    public static void jpgToTif(String jpgImage) {
    	 if (jpgImage == null || "".equals(jpgImage.trim())){
             return ;    
         }
         if (!new File(jpgImage).exists()){
         	log.info("系统找不到指定文件："+jpgImage);
             return ;
         }
         
        OutputStream outputStream = null;
        try {
            RenderedOp renderOp = JAI.create("fileload", jpgImage);
            String tifFilePath = jpgImage.substring(0, jpgImage.lastIndexOf("."))+".tif";
            outputStream = new FileOutputStream(tifFilePath);
            TIFFEncodeParam tiffParam = new TIFFEncodeParam();
            ImageEncoder imageEncoder = ImageCodec.createImageEncoder("TIFF", outputStream, tiffParam);
            imageEncoder.encode(renderOp);
            log.info("jpg2Tif 保存至： " + tifFilePath);
        } catch (FileNotFoundException e) {
            log.info(e.toString());
        } catch (IOException e) {
            log.info(e.toString());
        } finally {
            if (outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                }
                outputStream = null;
            }
        }
    }
    
    /**
     * tif 转 bmp
     * @param tifImage
     */
    public static void tifToBmp(String tifImage){
    	if (tifImage == null || "".equals(tifImage.trim())){
            return ;    
        }
        if (!new File(tifImage).exists()){
        	log.info("系统找不到指定文件："+tifImage);
            return ;
        }
    	RenderedOp src = JAI.create("fileload", tifImage);
    	try {
    		String bmpFilePath = tifImage.substring(0, tifImage.lastIndexOf("."))+".bmp";
			OutputStream os = new FileOutputStream(bmpFilePath);
			BMPEncodeParam param = new BMPEncodeParam();
			ImageEncoder enc = ImageCodec.createImageEncoder("BMP", os,param);
			enc.encode(src);
			os.close();//关闭流
		} catch (FileNotFoundException e) {
			log.info(e.toString());
		} catch (IOException e) {
			log.info(e.toString());
		}
    }
    
    
    /**
     * 不改变分辨率，放大或缩小图片
     * @param srcImg 源图片
     * @param desImg 结果图片
     * @return
     * @throws IOException 
     */
	public static boolean imgToSmall(String srcImg, String desImg) throws IOException{
    	 ImageWriter imgWrier;
         ImageWriteParam imgWriteParams;

         // 指定写图片的方式为 jpg
         imgWrier = ImageIO.getImageWritersByFormatName("jpg").next();
         imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(
                 null);
         // 要使用压缩，必须指定压缩方式为MODE_EXPLICIT
         imgWriteParams.setCompressionMode(imgWriteParams.MODE_EXPLICIT);
         // 这里指定压缩的程度，参数qality是取值0~1范围内，
         imgWriteParams.setCompressionQuality((float)0.1);
         imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED);
         ColorModel colorModel = ImageIO.read(new File(srcImg)).getColorModel();// ColorModel.getRGBdefault();
         // 指定压缩时使用的色彩模式
         imgWriteParams.setDestinationType(new ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
         
         File file = null;
         BufferedImage src = null;
         FileOutputStream out = null;
         try {
             if (srcImg==null||srcImg.isEmpty()) {
                 return false;
             } else {
                 file = new File(srcImg);
                 System.out.println(file.length());
                 src = ImageIO.read(file);
                 out = new FileOutputStream(desImg);

                 imgWrier.reset();
                 // 必须先指定 out值，才能调用write方法, ImageOutputStream可以通过任何
                 imgWrier.setOutput(ImageIO.createImageOutputStream(out));
                 // 调用write方法，就可以向输入流写图片
                 imgWrier.write(null, new IIOImage(src, null, null),
                         imgWriteParams);
                 out.flush();
                 out.close();
             }
         } catch (Exception e) {
             e.printStackTrace();
             return false;
         }
         return true;
    }
    
    //基于google工具jar对图片操作
    
    /**
     * 尺寸大小进行缩放
     * 
     * @throws IOException
     */
    private void test1() throws IOException {
        /*
         * size(width,height) 若图片横比200小，高比300小，不变
         * 若图片横比200小，高比300大，高缩小到300，图片比例不变 若图片横比200大，高比300小，横缩小到200，图片比例不变
         * 若图片横比200大，高比300大，图片按比例缩小，横为200或高为300
         */
        Thumbnails.of("images/test.jpg").size(200, 300).toFile("C:/image_200x300.jpg");
        Thumbnails.of("images/test.jpg").size(2560, 2048).toFile("C:/image_2560x2048.jpg");
    }

    /**
     * 按照比例进行缩放
     * 
     * @throws IOException
     */
    private void test2() throws IOException {
        /**
         * scale(比例)
         */
        Thumbnails.of("images/test.jpg").scale(0.25f).toFile("C:/image_25%.jpg");
        Thumbnails.of("images/test.jpg").scale(1.10f).toFile("C:/image_110%.jpg");
    }

    /**
     * 不按照比例，指定大小进行缩放
     * 
     * @throws IOException
     */
    private void test3() throws IOException {
        /**
         * keepAspectRatio(false) 默认是按照比例缩放的
         */
        Thumbnails.of("images/test.jpg").size(120, 120).keepAspectRatio(false).toFile("C:/image_120x120.jpg");
    }

    /**
     * 旋转
     * 
     * @throws IOException
     */
    private void test4() throws IOException {
        /**
         * rotate(角度),正数：顺时针 负数：逆时针
         */
        Thumbnails.of("images/test.jpg").size(1280, 1024).rotate(90).toFile("C:/image+90.jpg");
        Thumbnails.of("images/test.jpg").size(1280, 1024).rotate(-90).toFile("C:/iamge-90.jpg");
    }

    /**
     * 水印
     * 
     * @throws IOException
     */
    private void test5() throws IOException {
        /**
         * watermark(位置，水印图，透明度)
         */
        Thumbnails.of("images/test.jpg").size(1280, 1024).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("images/watermark.png")), 0.5f)
                .outputQuality(0.8f).toFile("C:/image_watermark_bottom_right.jpg");
        Thumbnails.of("images/test.jpg").size(1280, 1024).watermark(Positions.CENTER, ImageIO.read(new File("images/watermark.png")), 0.5f)
                .outputQuality(0.8f).toFile("C:/image_watermark_center.jpg");
    }

    /**
     * 裁剪
     * 
     * @throws IOException
     */
    private void test6() throws IOException {
        /**
         * 图片中心400*400的区域
         */
        Thumbnails.of("images/test.jpg").sourceRegion(Positions.CENTER, 400, 400).size(200, 200).keepAspectRatio(false)
                .toFile("C:/image_region_center.jpg");
        /**
         * 图片右下400*400的区域
         */
        Thumbnails.of("images/test.jpg").sourceRegion(Positions.BOTTOM_RIGHT, 400, 400).size(200, 200).keepAspectRatio(false)
                .toFile("C:/image_region_bootom_right.jpg");
        /**
         * 指定坐标
         */
        Thumbnails.of("images/test.jpg").sourceRegion(600, 500, 400, 400).size(200, 200).keepAspectRatio(false).toFile("C:/image_region_coord.jpg");
    }

    /**
     * 转化图像格式
     * 
     * @throws IOException
     */
    private void test7() throws IOException {
        /**
         * outputFormat(图像格式)
         */
        Thumbnails.of("images/test.jpg").size(1280, 1024).outputFormat("png").toFile("C:/image_1280x1024.png");
        Thumbnails.of("images/test.jpg").size(1280, 1024).outputFormat("gif").toFile("C:/image_1280x1024.gif");
    }

    /**
     * 输出到OutputStream
     * 
     * @throws IOException
     */
    private void test8() throws IOException {
        /**
         * toOutputStream(流对象)
         */
        OutputStream os = new FileOutputStream("C:/image_1280x1024_OutputStream.png");
        Thumbnails.of("images/test.jpg").size(1280, 1024).toOutputStream(os);
    }

    /**
     * 输出到BufferedImage
     * 
     * @throws IOException
     */
    private void test9() throws IOException {
        /**
         * asBufferedImage() 返回BufferedImage
         */
        BufferedImage thumbnail = Thumbnails.of("images/test.jpg").size(1280, 1024).asBufferedImage();
        ImageIO.write(thumbnail, "jpg", new File("C:/image_1280x1024_BufferedImage.jpg"));
    }
}